package cn.caplike.demo.nio._2021.zerocopy;

import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;

/**
 * Description: NIO
 *
 * @author LiKe
 * @version 1.0.0
 * @date 2022-10-06 12:36
 */
public class SocketNIO {

    public static class NewServer {
        public static void main(String[] args) throws IOException {
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();

            ServerSocket serverSocket = serverSocketChannel.socket();
            serverSocket.setReuseAddress(true); // See: javadoc
            serverSocket.bind(new InetSocketAddress(8899));

            ByteBuffer buffer = ByteBuffer.allocate(4096);
            while (true) {
                final SocketChannel socketChannel = serverSocketChannel.accept();
                socketChannel.configureBlocking(true); // default, 注意与使用了Selector时的区别

                int readCount = 0;
                while (-1 != readCount) {
                    readCount = socketChannel.read(buffer);
                    buffer.rewind();
                }
            }
        }
    }

    // -------------------------------------------------------------------------------------------------------------------------------------

    public static class NewClient {
        static String fileName = "<绝对路径>";

        public static void main(String[] args) throws Exception {
            SocketChannel socketChannel = SocketChannel.open();
            socketChannel.connect(new InetSocketAddress("127.0.0.1", 8899));
            socketChannel.configureBlocking(true);

            FileChannel fileChannel = new FileInputStream(fileName).getChannel();
            long startTime = System.currentTimeMillis();
            final long transferCount = fileChannel.transferTo(0, fileChannel.size(), socketChannel); // ! zero-copy
            System.out.println("send total: " + transferCount + ", cost: " + (System.currentTimeMillis() - startTime));
        }
    }

}
